This package uses two-dimensional particle trajectories to study the distribution of particles relative to surrounding cellular structures. It calculates the nearest distance between each point of a trajectory and surrounding structures reprensented as thresholded binary images taken from a corresponding sequence of reference images. It can also be used to randomize the trajectories within a pre-defined area which allows you to compare the positioning of particles relative to other cellular structures to a stochastic distribution.
This R package that can be downloaded from GitHub. To install this package from GitHub, the devtools package must first be installed. To install devtools, start R and enter:
install.packages("devtools")
library(devtools)Then to install the CloseEnough enter:
install_github("MaxLev/CloseEnough")
Once the CloseEnough package is installed, it can be loaded by the following command:
library(CloseEnough)This package depends on the EBImage package to upload and display images. To start off, let us display an image distributed with the CloseEnough package.
## Load image
data(cellmovie)
## Display image
display(cellmovie, method = "browser")Let us display the cell outline and overlay the particle trajectories on the image.
## Load cell outline
data(outline)
## Load trajectory
data(trajectory)
## Display image
display(cellmovie, method = "raster")
## Trace outline
lines(outline$x, outline$y, type = "l", col = "white")
## Draw trajectories
ntraj = nlevels(trajectory["trajectory"])
for (i in 1:ntraj) {
traj_i <- subset(trajectory["data"], trajectory == i)
lines(traj_i$x, traj_i$y, type="l", col = "white")
}Let us rotate the particle trajectories to the right by a 90 degree angle:
rotated_traj <- rotate_trajectory(trajectory, 90)and reflect them along the y axis
mirror_traj <- mirror_trajectory(trajectory, axis = "y")Now let us visualize those different trajectories on a simple cell mask
## Load cell mask
data(cellmask)
## Display image
display(cellmask, method = "raster")
## Draw trajectories in black
ntraj = nlevels(trajectory["trajectory"])
for (i in 1:ntraj) {
traj_i <- subset(trajectory["data"], trajectory == i)
lines(traj_i$x, traj_i$y, type="l", col = "black")
}
## Add the rotated trajectories in blue
ntraj = nlevels(rotated_traj["trajectory"])
for (i in 1:ntraj) {
traj_i <- subset(rotated_traj["data"], trajectory == i)
lines(traj_i$x, traj_i$y, type="l", col = "blue")
}
## And the reflected trajectories in green
ntraj = nlevels(mirror_traj["trajectory"])
for (i in 1:ntraj) {
traj_i <- subset(mirror_traj["data"], trajectory == i)
lines(traj_i$x, traj_i$y, type="l", col = "green")
}CloseEnough can easily randomize particle trajectories within a given area provided by a binary mask image. This provides valuable information regarding the spatial distribution of particles within a cellular context. As an example, let us randomize Panx2 foci trajectories within the cytoplasm and observe how their distribution changes relative to the mitochondrial network.
## Randomize trajectories using an image mask as reference.
rand_traj <- randomize(trajectory, cellmask)
## Display image
display(cellmovie, method = "raster")
#> Only the first frame of the image stack is displayed.
#> To display all frames use 'all = TRUE'.
## Trace cell outline
lines(outline$x, outline$y, type = "l", col = "white")
## Draw trajectories in white
ntraj = nlevels(trajectory["trajectory"])
for (i in 1:ntraj) {
traj_i <- subset(trajectory["data"], trajectory == i)
lines(traj_i$x, traj_i$y, type="l", col = "white")
}
## Add the randomized trajectories in blue
ntraj = nlevels(rand_traj["trajectory"])
for (i in 1:ntraj) {
traj_i <- subset(rand_traj["data"], trajectory == i)
lines(traj_i$x, traj_i$y, type="l", col = "blue")
}CloseEnough can calculate the minimal distance between the particles and other cellular structures within a thresholded binary image. In this example, we will calculate the minimal distance between every single Panx2 foci identified in all trajectories and the mitochondrial network. We will also performed the same calculations the particle trajectories whieh were randomized within the cytoplasm earlier.
## Load the thresholded mask of the mitochondrial network
data(mitomask)
## Calculate minimal distance between Panx2 foci and mitochondria
# Channel refers to the channel that needs to be used within the binary image. In this case there is only one channel.
Panx2_mito <- min_distance(mitomask, trajectory, channel = 1)
## Calculate minimal distance between randomized Panx2 trajectories and mitochondria
rand_mito <- min_distance(mitomask, rand_traj, channel = 1)
## The value is currently in pixel and can be converted if the size of a pixel was provided. In this case
## the pixel size was provided in nanometer and will be converted to micrometer
Panx2_mito$min_distance <- Panx2_mito$min_distance * trajectory["pixel_size"]/1000
rand_mito$min_distance <- rand_mito$min_distance * trajectory["pixel_size"]/1000Finally, these values can be visualized as probability distributions using any R graphic tools. In this case, we will use the package ggplot2.
options(scipen = 999)
## Let us first group the data
Panx2_mito$random <- FALSE
rand_mito$random <- TRUE
Panx2_mito <- rbind(Panx2_mito, rand_mito)
graph <- ggplot(data = Panx2_mito) +
geom_density(aes(x = min_distance, color = random, fill = random),
alpha = 0.75, size = 0.8) +
theme_bw() +
theme(text = element_text(size = 12),
plot.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
axis.line = element_line(color = 'black'),
legend.title = element_blank(),
legend.position = "top",
legend.margin = margin(c(5, 5, 5, 0)),
legend.text = element_text(margin = margin(r = 10, unit = "pt"))) +
xlab(expression(paste("Distance to mitochondria (in ", mu,"m)"))) +
ylab("Density") +
scale_color_manual(values = c("#d95f02", "#7570b3")) +
guides(color = FALSE) +
scale_fill_manual(labels = c("Panx2", "Randomized"), values = c("#d95f02", "#7570b3")) +
coord_cartesian(xlim = c(0.001, 10))
## Display graph
graph